// ============================================================================
//
// Copyright (C) 2006-2007 Dengues
//
// Google Group: http://groups.google.com/group/dengues
// QQ Group: 24885404
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// ============================================================================
package org.dengues.designer.ui.database.parts;

import org.dengues.designer.ui.database.figures.ForeignKeyFigure;
import org.dengues.designer.ui.database.policies.ForeignKeyEditPolicy;
import org.dengues.designer.ui.database.router.FKRouter;
import org.dengues.model.database.DatabasePackage;
import org.dengues.model.database.EMFDataType;
import org.dengues.model.database.ForeignKey;
import org.dengues.ui.query.JoinOptionsDialog;
import org.eclipse.draw2d.ColorConstants;
import org.eclipse.draw2d.Graphics;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.PolylineConnection;
import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.Notifier;
import org.eclipse.gef.ConnectionEditPart;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.EditPolicy;
import org.eclipse.gef.Request;
import org.eclipse.gef.RequestConstants;
import org.eclipse.gef.commands.Command;
import org.eclipse.gef.commands.CommandStack;
import org.eclipse.gef.editparts.AbstractConnectionEditPart;
import org.eclipse.gef.editpolicies.ConnectionEndpointEditPolicy;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.PlatformUI;

/**
 * Qiang.Zhang.Adolf@gmail.com class global comment. Detailled comment <br/>
 * 
 * $Id: Dengues.epf 2007-12-17 qiang.zhang $
 * 
 */
public class ForeignKeyEditPart extends AbstractConnectionEditPart {

    private final ConnectionAdapter adapter = new ConnectionAdapter(this);

    /**
     * Qiang.Zhang.Adolf@gmail.com ForeignKeyEditPart class global comment. Detailled comment <br/>
     * 
     * $Id: Dengues.epf 2007-12-17 qiang.zhang $
     * 
     */
    private class ConnectionAdapter implements Adapter {

        private Notifier target;

        private final ConnectionEditPart editPart;

        /**
         * Qiang.Zhang.Adolf@gmail.com ConnectionAdapter constructor comment.
         * 
         * @param part
         */
        public ConnectionAdapter(ConnectionEditPart part) {
            this.editPart = part;
        }

        /**
         * @see org.eclipse.emf.common.notify.Adapter#notifyChanged(org.eclipse.emf.common.notify.Notification)
         */
        public void notifyChanged(Notification notification) {
            int type = notification.getEventType();
            int featureId = notification.getFeatureID(DatabasePackage.class);
            if (type == Notification.SET) {
                switch (featureId) {
                case DatabasePackage.FOREIGN_KEY__SOURCE:
                    ((PolylineConnection) getFigure()).setLineStyle(Graphics.LINE_DASH);
                    ((PolylineConnection) getFigure()).setLineStyle(Graphics.LINE_SOLID);
                    refreshVisuals();
                    break;
                }
            }
        }

        /**
         * @see org.eclipse.emf.common.notify.Adapter#setTarget(org.eclipse.emf.common.notify.Notifier)
         */
        public void setTarget(Notifier newTarget) {
            target = newTarget;
        }

        /**
         * @see org.eclipse.emf.common.notify.Adapter#isAdapterForType(java.lang.Object)
         */
        public boolean isAdapterForType(Object type) {
            return (getModel().getClass() == type);
        }

        /**
         * @see org.eclipse.emf.common.notify.Adapter#getTarget()
         */
        public Notifier getTarget() {
            return target;
        }

    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.gef.editparts.AbstractEditPart#refreshVisuals()
     */
    @Override
    protected void refreshVisuals() {
    }

    /**
     * Qiang.Zhang.Adolf@gmail.com ForeignKeyEditPart constructor comment.
     */
    public ForeignKeyEditPart() {

    }

    private ForeignKeyFigure keyFigure;

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.gef.editparts.AbstractConnectionEditPart#createFigure()
     */
    @Override
    protected IFigure createFigure() {
        keyFigure = new ForeignKeyFigure(getCastModel());
        keyFigure.setConnectionRouter(new FKRouter());
        return keyFigure;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.gef.editparts.AbstractGraphicalEditPart#activate()
     */
    @Override
    public void activate() {
        if (!isActive()) {
            if (getModel() != null) {
                getCastModel().eAdapters().add(adapter);
            }
            super.activate();
        }
    }

    /**
     * Qiang.Zhang.Adolf@gmail.com Comment method "getCastModel".
     * 
     * @return
     */
    private ForeignKey getCastModel() {
        return (ForeignKey) getModel();
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.gef.editparts.AbstractGraphicalEditPart#deactivate()
     */
    @Override
    public void deactivate() {
        if (isActive()) {
            if (getModel() != null) {
                getCastModel().eAdapters().remove(adapter);
            }
            super.deactivate();
        }
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.gef.editparts.AbstractEditPart#createEditPolicies()
     */
    @Override
    protected void createEditPolicies() {
        // Selection handle edit policy.
        // Makes the connection show a feedback, when selected by the user.
        installEditPolicy(EditPolicy.CONNECTION_ENDPOINTS_ROLE, new ConnectionEndpointEditPolicy());
        // Allows the removal of the connection model element
        installEditPolicy(EditPolicy.COMPONENT_ROLE, new ForeignKeyEditPolicy());
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.gef.editparts.AbstractEditPart#setSelected(int)
     */
    @Override
    public void setSelected(int value) {
        super.setSelected(value);
        if (value != EditPart.SELECTED_NONE)
            ((PolylineConnection) getFigure()).setForegroundColor(ColorConstants.black);
        else
            ((PolylineConnection) getFigure()).setForegroundColor(ColorConstants.orange);
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.gef.editparts.AbstractEditPart#performRequest(org.eclipse.gef.Request)
     */
    @Override
    public void performRequest(Request req) {
        IWorkbenchPart part = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getActiveEditor();
        CommandStack cmdStack = (CommandStack) part.getAdapter(CommandStack.class);
        if (RequestConstants.REQ_OPEN.equals(req.getType())) {
            int value = getCastModel().getSource().getTable().getDbDiagram().getEmfType().getValue();
            switch (value) {
            case EMFDataType.QUERY_VALUE:
                JoinOptionsDialog dialog = new JoinOptionsDialog(Display.getDefault().getActiveShell(), getCastModel());
                if (JoinOptionsDialog.OK == dialog.open()) {
                    cmdStack.execute(new Command() {

                        /*
                         * (non-Javadoc)
                         * 
                         * @see org.eclipse.gef.commands.Command#execute()
                         */
                        @Override
                        public void execute() {
                            keyFigure.updateJoinImage();
                        }
                    });
                }
                break;
            }
        }
        super.performRequest(req);
    }
}
